package com.ptp.backendcertms.basiccompnents.http;

import com.ptp.backendcertms.api.external.dto.res.ResponseDto;
import com.ptp.backendcertms.api.external.dto.res.ResponseEmptyDto;
import com.ptp.backendcertms.api.internal.exception.SystemException;
import com.ptp.backendcertms.basiccompnents.exception.IExceptionHandler;
import com.ptp.backendcertms.basiccompnents.log.TraceUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Objects;
import java.util.concurrent.Callable;

import static com.ptp.backendcertms.api.internal.constant.CertMsConstant.ENGLISH_COMMA_SEPARATOR;

/**
 * 响应包装器
 *
 * @author scc
 * @date 2025/5/1
 */
@Slf4j
@Component
public class ResponseWrapper {

    private static IExceptionHandler myExceptionHandler;

    @Resource
    private IExceptionHandler exceptionHandler;

    @PostConstruct
    public void init() {
        myExceptionHandler = exceptionHandler;
    }

    /**
     * 响应包装器
     * （1）不校验入参
     * （2）返回空业务参数响应
     */
    public static ResponseEmptyDto response(String name, Runnable task) {
        ResponseEmptyDto responseDto = ResponseEmptyDto.createEmptyResponseDto();
        try {
            task.run();
            responseDto.successEmptyWrapper();
        } catch (SystemException systemException) {
            log.warn("ResponseWrapper:{}自定义响应异常:{}", name, systemException.getErrorMsg());
            responseDto.failEmptyWrapper(systemException.getErrorCode(), systemException.getErrorMsg());
        } catch (Exception e) {
            log.error("ResponseWrapper:{}响应异常", name, e);
            responseDto.failEmptyWrapper("抱歉，服务器异常，请联系管理员，我们将快马加鞭排除异常！");
            myExceptionHandler.addExceptionMsg(name, TraceUtil.getTraceId(), e.getMessage());
        }
        return responseDto;
    }

    /**
     * 响应包装器
     * （1）不校验入参
     * （2）返回业务参数响应
     */
    public static <T> ResponseDto<T> responseReturn(String name, Callable<T> callable) {
        ResponseDto<T> responseDto = ResponseDto.createResponseDto();
        try {
            responseDto.successWrapper(callable.call());
        } catch (SystemException systemException) {
            log.warn("ResponseWrapper:{}自定义响应异常:{}", name, systemException.getErrorMsg());
            responseDto.failWrapper(systemException.getErrorCode(), systemException.getErrorMsg());
        } catch (Exception e) {
            log.error("ResponseWrapper:{}响应异常", name, e);
            responseDto.failWrapper("抱歉，服务器异常，请联系管理员，我们将快马加鞭排除异常！");
            myExceptionHandler.addExceptionMsg(name, TraceUtil.getTraceId(), e.getMessage());
        }
        return responseDto;
    }

    /**
     * 响应包装器
     * （1）校验入参
     * （2）返回空业务参数响应
     */
    public static ResponseEmptyDto responseWithValid(BindingResult bindingResult, String name, Runnable task) {
        ResponseEmptyDto responseDto = emptyParamValidMsg(bindingResult);
        if (Objects.nonNull(responseDto)) {
            return responseDto;
        }
        return response(name, task);
    }

    /**
     * 响应包装器
     * （1）校验入参
     * （2）返回业务参数响应
     */
    public static <T> ResponseDto<T> responseReturnWithValid(BindingResult bindingResult, String name, Callable<T> callable) {
        ResponseDto<T> responseDto = paramValidMsg(bindingResult);
        if (Objects.nonNull(responseDto)) {
            return responseDto;
        }
        return responseReturn(name, callable);
    }

    /**
     * 参数校验
     *
     * @param bindingResult 参数校验
     */
    private static <T> ResponseDto<T> paramValidMsg(BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            ResponseDto<T> responseDto = ResponseDto.createResponseDto();
            StringBuilder stringBuilder = new StringBuilder();
            bindingResult.getAllErrors().forEach(errRes -> stringBuilder.append(errRes.getDefaultMessage()).append(ENGLISH_COMMA_SEPARATOR));
            responseDto.failWrapper(stringBuilder.substring(0, stringBuilder.length() - 1));
            return responseDto;
        }
        return null;
    }

    /**
     * 参数校验
     *
     * @param bindingResult 参数校验
     */
    private static ResponseEmptyDto emptyParamValidMsg(BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            ResponseEmptyDto responseDto = ResponseEmptyDto.createEmptyResponseDto();
            StringBuilder stringBuilder = new StringBuilder();
            bindingResult.getAllErrors().forEach(errRes -> stringBuilder.append(errRes.getDefaultMessage()).append(ENGLISH_COMMA_SEPARATOR));
            responseDto.failEmptyWrapper(stringBuilder.substring(0, stringBuilder.length() - 1));
            return responseDto;
        }
        return null;
    }


}
